package com.lifeverse.controller;

import com.lifeverse.common.ApiResponse;
import com.lifeverse.entity.PerformanceMetric;
import com.lifeverse.entity.enums.MetricStatus;
import com.lifeverse.entity.enums.MetricType;
import com.lifeverse.service.PerformanceMonitoringService;
import com.lifeverse.service.PerformanceOptimizationService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 性能监控控制器
 * 提供性能指标查询、监控和优化功能的REST API
 */
@RestController
@RequestMapping("/api/performance")
@RequiredArgsConstructor
@Slf4j
@Tag(name = "性能监控管理", description = "性能指标监控、分析和优化API")
public class PerformanceController {
    
    private final PerformanceMonitoringService performanceMonitoringService;
    private final PerformanceOptimizationService performanceOptimizationService;
    
    /**
     * 记录性能指标
     */
    @PostMapping("/metrics")
    @Operation(summary = "记录性能指标", description = "手动记录一个性能指标")
    @PreAuthorize("hasRole('ADMIN') or hasRole('MONITOR')")
    public ResponseEntity<ApiResponse<PerformanceMetric>> recordMetric(
            @Parameter(description = "指标名称") @RequestParam String metricName,
            @Parameter(description = "指标类型") @RequestParam MetricType metricType,
            @Parameter(description = "指标值") @RequestParam BigDecimal metricValue,
            @Parameter(description = "指标单位") @RequestParam(required = false) String unit,
            @Parameter(description = "组件名称") @RequestParam(required = false) String componentName) {
        
        try {
            PerformanceMetric metric = performanceMonitoringService.recordMetric(
                    metricName, metricType, metricValue, unit, componentName);
            return ResponseEntity.ok(ApiResponse.success(metric));
        } catch (Exception e) {
            log.error("记录性能指标失败", e);
            return ResponseEntity.ok(ApiResponse.error("记录性能指标失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取最新的性能指标
     */
    @GetMapping("/metrics/latest/{metricName}")
    @Operation(summary = "获取最新指标", description = "获取指定名称的最新性能指标")
    @PreAuthorize("hasRole('ADMIN') or hasRole('MONITOR') or hasRole('USER')")
    public ResponseEntity<ApiResponse<PerformanceMetric>> getLatestMetric(
            @Parameter(description = "指标名称") @PathVariable String metricName,
            @Parameter(description = "组件名称") @RequestParam(required = false) String componentName) {
        
        try {
            Optional<PerformanceMetric> metric;
            if (componentName != null) {
                metric = performanceMonitoringService.getLatestMetric(metricName, componentName);
            } else {
                metric = performanceMonitoringService.getLatestMetric(metricName);
            }
            
            if (metric.isPresent()) {
                return ResponseEntity.ok(ApiResponse.success(metric.get()));
            } else {
                return ResponseEntity.ok(ApiResponse.error("未找到指定的性能指标"));
            }
        } catch (Exception e) {
            log.error("获取最新性能指标失败: metricName={}", metricName, e);
            return ResponseEntity.ok(ApiResponse.error("获取最新性能指标失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取指标历史数据
     */
    @GetMapping("/metrics/history/{metricName}")
    @Operation(summary = "获取指标历史", description = "获取指定时间范围内的指标历史数据")
    @PreAuthorize("hasRole('ADMIN') or hasRole('MONITOR') or hasRole('USER')")
    public ResponseEntity<ApiResponse<List<PerformanceMetric>>> getMetricHistory(
            @Parameter(description = "指标名称") @PathVariable String metricName,
            @Parameter(description = "组件名称") @RequestParam(required = false) String componentName,
            @Parameter(description = "开始时间") @RequestParam 
            @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam 
            @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime) {
        
        try {
            List<PerformanceMetric> metrics;
            if (componentName != null) {
                metrics = performanceMonitoringService.getMetricHistory(metricName, componentName, startTime, endTime);
            } else {
                metrics = performanceMonitoringService.getMetricHistory(metricName, startTime, endTime);
            }
            
            return ResponseEntity.ok(ApiResponse.success(metrics));
        } catch (Exception e) {
            log.error("获取指标历史数据失败: metricName={}", metricName, e);
            return ResponseEntity.ok(ApiResponse.error("获取指标历史数据失败: " + e.getMessage()));
        }
    }
    
    /**
     * 分页查询性能指标
     */
    @GetMapping("/metrics")
    @Operation(summary = "分页查询指标", description = "根据条件分页查询性能指标")
    @PreAuthorize("hasRole('ADMIN') or hasRole('MONITOR') or hasRole('USER')")
    public ResponseEntity<ApiResponse<Page<PerformanceMetric>>> getMetrics(
            @Parameter(description = "指标类型") @RequestParam(required = false) MetricType metricType,
            @Parameter(description = "指标状态") @RequestParam(required = false) MetricStatus status,
            @Parameter(description = "组件名称") @RequestParam(required = false) String componentName,
            @Parameter(description = "页码") @RequestParam(defaultValue = "0") int page,
            @Parameter(description = "页大小") @RequestParam(defaultValue = "20") int size,
            @Parameter(description = "排序字段") @RequestParam(defaultValue = "measuredAt") String sortBy,
            @Parameter(description = "排序方向") @RequestParam(defaultValue = "desc") String sortDir) {
        
        try {
            Sort sort = Sort.by(Sort.Direction.fromString(sortDir), sortBy);
            Pageable pageable = PageRequest.of(page, size, sort);
            
            Page<PerformanceMetric> metrics;
            if (metricType != null) {
                metrics = performanceMonitoringService.getMetricsByType(metricType, pageable);
            } else if (status != null) {
                metrics = performanceMonitoringService.getMetricsByStatus(status, pageable);
            } else {
                // 如果没有指定条件，返回需要关注的指标
                metrics = performanceMonitoringService.getMetricsNeedingAttention(pageable);
            }
            
            return ResponseEntity.ok(ApiResponse.success(metrics));
        } catch (Exception e) {
            log.error("分页查询性能指标失败", e);
            return ResponseEntity.ok(ApiResponse.error("分页查询性能指标失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取需要关注的指标
     */
    @GetMapping("/metrics/attention")
    @Operation(summary = "获取需要关注的指标", description = "获取状态为警告、异常或临界的指标")
    @PreAuthorize("hasRole('ADMIN') or hasRole('MONITOR') or hasRole('USER')")
    public ResponseEntity<ApiResponse<Page<PerformanceMetric>>> getMetricsNeedingAttention(
            @Parameter(description = "页码") @RequestParam(defaultValue = "0") int page,
            @Parameter(description = "页大小") @RequestParam(defaultValue = "20") int size) {
        
        try {
            Pageable pageable = PageRequest.of(page, size);
            Page<PerformanceMetric> metrics = performanceMonitoringService.getMetricsNeedingAttention(pageable);
            
            return ResponseEntity.ok(ApiResponse.success(metrics));
        } catch (Exception e) {
            log.error("获取需要关注的指标失败", e);
            return ResponseEntity.ok(ApiResponse.error("获取需要关注的指标失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取异常指标
     */
    @GetMapping("/metrics/anomalies")
    @Operation(summary = "获取异常指标", description = "获取指定时间范围内的异常指标")
    @PreAuthorize("hasRole('ADMIN') or hasRole('MONITOR')")
    public ResponseEntity<ApiResponse<List<PerformanceMetric>>> getAnomalies(
            @Parameter(description = "开始时间") @RequestParam 
            @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam 
            @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime) {
        
        try {
            List<PerformanceMetric> anomalies = performanceMonitoringService.getAnomalies(startTime, endTime);
            return ResponseEntity.ok(ApiResponse.success(anomalies));
        } catch (Exception e) {
            log.error("获取异常指标失败", e);
            return ResponseEntity.ok(ApiResponse.error("获取异常指标失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取系统健康概览
     */
    @GetMapping("/health/overview")
    @Operation(summary = "获取系统健康概览", description = "获取系统整体健康状况概览")
    @PreAuthorize("hasRole('ADMIN') or hasRole('MONITOR') or hasRole('USER')")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getSystemHealthOverview() {
        
        try {
            Map<String, Object> overview = performanceMonitoringService.getSystemHealthOverview();
            return ResponseEntity.ok(ApiResponse.success(overview));
        } catch (Exception e) {
            log.error("获取系统健康概览失败", e);
            return ResponseEntity.ok(ApiResponse.error("获取系统健康概览失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取性能趋势摘要
     */
    @GetMapping("/trends/summary")
    @Operation(summary = "获取性能趋势摘要", description = "获取指定时间范围内的性能趋势摘要")
    @PreAuthorize("hasRole('ADMIN') or hasRole('MONITOR') or hasRole('USER')")
    public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getPerformanceTrendSummary(
            @Parameter(description = "开始时间") @RequestParam 
            @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam 
            @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime) {
        
        try {
            List<Map<String, Object>> trendSummary = performanceMonitoringService.getPerformanceTrendSummary(startTime, endTime);
            return ResponseEntity.ok(ApiResponse.success(trendSummary));
        } catch (Exception e) {
            log.error("获取性能趋势摘要失败", e);
            return ResponseEntity.ok(ApiResponse.error("获取性能趋势摘要失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取指标统计信息
     */
    @GetMapping("/metrics/statistics/{metricName}")
    @Operation(summary = "获取指标统计", description = "获取指定指标在时间范围内的统计信息")
    @PreAuthorize("hasRole('ADMIN') or hasRole('MONITOR') or hasRole('USER')")
    public ResponseEntity<ApiResponse<Map<String, Object>>> getMetricStatistics(
            @Parameter(description = "指标名称") @PathVariable String metricName,
            @Parameter(description = "开始时间") @RequestParam 
            @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam 
            @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime) {
        
        try {
            Map<String, Object> statistics = performanceMonitoringService.getMetricStatistics(metricName, startTime, endTime);
            return ResponseEntity.ok(ApiResponse.success(statistics));
        } catch (Exception e) {
            log.error("获取指标统计信息失败: metricName={}", metricName, e);
            return ResponseEntity.ok(ApiResponse.error("获取指标统计信息失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取所有组件名称
     */
    @GetMapping("/components")
    @Operation(summary = "获取所有组件", description = "获取系统中所有的组件名称")
    @PreAuthorize("hasRole('ADMIN') or hasRole('MONITOR') or hasRole('USER')")
    public ResponseEntity<ApiResponse<List<String>>> getAllComponentNames() {
        
        try {
            List<String> componentNames = performanceMonitoringService.getAllComponentNames();
            return ResponseEntity.ok(ApiResponse.success(componentNames));
        } catch (Exception e) {
            log.error("获取所有组件名称失败", e);
            return ResponseEntity.ok(ApiResponse.error("获取所有组件名称失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取所有指标名称
     */
    @GetMapping("/metrics/names")
    @Operation(summary = "获取所有指标名称", description = "获取系统中所有的指标名称")
    @PreAuthorize("hasRole('ADMIN') or hasRole('MONITOR') or hasRole('USER')")
    public ResponseEntity<ApiResponse<List<String>>> getAllMetricNames() {
        
        try {
            List<String> metricNames = performanceMonitoringService.getAllMetricNames();
            return ResponseEntity.ok(ApiResponse.success(metricNames));
        } catch (Exception e) {
            log.error("获取所有指标名称失败", e);
            return ResponseEntity.ok(ApiResponse.error("获取所有指标名称失败: " + e.getMessage()));
        }
    }
    
    /**
     * 生成性能分析报告
     */
    @GetMapping("/analysis/report")
    @Operation(summary = "生成性能分析报告", description = "生成指定时间范围内的性能分析报告")
    @PreAuthorize("hasRole('ADMIN') or hasRole('MONITOR')")
    public ResponseEntity<ApiResponse<PerformanceOptimizationService.PerformanceAnalysisReport>> generatePerformanceAnalysisReport(
            @Parameter(description = "开始时间") @RequestParam 
            @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam 
            @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime) {
        
        try {
            PerformanceOptimizationService.PerformanceAnalysisReport report = 
                    performanceOptimizationService.generatePerformanceAnalysisReport(startTime, endTime);
            return ResponseEntity.ok(ApiResponse.success(report));
        } catch (Exception e) {
            log.error("生成性能分析报告失败", e);
            return ResponseEntity.ok(ApiResponse.error("生成性能分析报告失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取优化建议
     */
    @GetMapping("/optimization/recommendations")
    @Operation(summary = "获取优化建议", description = "获取指定时间范围内的性能优化建议")
    @PreAuthorize("hasRole('ADMIN') or hasRole('MONITOR')")
    public ResponseEntity<ApiResponse<List<PerformanceOptimizationService.OptimizationRecommendation>>> getOptimizationRecommendations(
            @Parameter(description = "开始时间") @RequestParam 
            @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
            @Parameter(description = "结束时间") @RequestParam 
            @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime) {
        
        try {
            List<PerformanceOptimizationService.OptimizationRecommendation> recommendations = 
                    performanceOptimizationService.getOptimizationRecommendations(startTime, endTime);
            return ResponseEntity.ok(ApiResponse.success(recommendations));
        } catch (Exception e) {
            log.error("获取优化建议失败", e);
            return ResponseEntity.ok(ApiResponse.error("获取优化建议失败: " + e.getMessage()));
        }
    }
    
    /**
     * 获取指标类型枚举
     */
    @GetMapping("/metrics/types")
    @Operation(summary = "获取指标类型", description = "获取所有可用的指标类型")
    public ResponseEntity<ApiResponse<MetricType[]>> getMetricTypes() {
        return ResponseEntity.ok(ApiResponse.success(MetricType.values()));
    }
    
    /**
     * 获取指标状态枚举
     */
    @GetMapping("/metrics/statuses")
    @Operation(summary = "获取指标状态", description = "获取所有可用的指标状态")
    public ResponseEntity<ApiResponse<MetricStatus[]>> getMetricStatuses() {
        return ResponseEntity.ok(ApiResponse.success(MetricStatus.values()));
    }
}